package com.example.framework;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.Target;
import com.example.framework.databinding.ActivityMainBinding;
import com.google.gson.Gson;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.internal.Util;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    public final static int WEATHER_ID = 1;
    public final static int WEB_ID = 2;

    //数据接口地址
    public final static String WEATHER_URL = "http://apis.juhe.cn/simpleWeather/query";
    // 天气预报接口请求Key
    public static String API_KEY = "8558d229e191278eaef1a355631621e4";

    private ActivityMainBinding binding;
    private final Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == WEATHER_ID) {
                final Weather weather = (Weather) msg.obj;
                if (weather.getErrorCode() == 0) {
                    Toast.makeText(MainActivity.this, weather.getReason(), Toast.LENGTH_SHORT).show();

                    String result =
                            "\n当前温度：" + weather.getResult().getRealtime().getTemperature() +
                                    "\n当前天气：" + weather.getResult().getRealtime().getInfo() +
                                    "\n空气质量：" + weather.getResult().getRealtime().getAqi() +
                                    "\n明天天气：" + weather.getResult().getFuture().get(0).getWeather() +
                                    "\n明天温度：" + weather.getResult().getFuture().get(0).getTemperature() +
                                    "\n后天天气：" + weather.getResult().getFuture().get(1).getWeather() +
                                    "\n后天温度：" + weather.getResult().getFuture().get(1).getTemperature();
                    binding.tvResponse.setText(result);
                }
            } else if (msg.what == WEB_ID) {
                String result = (String) msg.obj;
                binding.tvResponse.setText("Web请求返回：" + result);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btnWeather.setOnClickListener(this);
        binding.btnApi.setOnClickListener(this);
        binding.btnRequest.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        if (id == R.id.btn_weather) {
            String city = binding.etCity.getText().toString();
            if (TextUtils.isEmpty(city)) {
                Toast.makeText(this, "城市不能为空", Toast.LENGTH_SHORT).show();
            }
            getWeather(city);
        } else if (id == R.id.btn_request) {
            GlideApp.with(this)
                    .load("https://cdn.pixabay.com/photo/2020/03/31/19/20/dog-4988985__340.jpg")
                    .centerCrop()  // 居中
                    .circleCrop()  // 圆形
                    .skipMemoryCache(true)  // 关闭内存缓存
                    .diskCacheStrategy(DiskCacheStrategy.NONE) // 关闭磁盘缓存
                    .override(Target.SIZE_ORIGINAL)  // 指定尺寸
                    .placeholder(R.drawable.pic)     // 临时占位符
                    .error(R.drawable.ic_error)      // 错误占位符
                    .into(binding.ivPic);
        } else if (id == R.id.btn_api) {
            // get请求
            doGet("http://10.0.2.2:8080/android/hello", "");

            // post请求
            // login("http://10.0.2.2:8080/android/login", new User("android", "111111"));
        }
    }

    /**
     * GET方式的网络请求
     *
     * @param httpUrl    网址
     * @param queryParam 请求字符串，格式为key1=value1&key2=value2
     * @return 服务器端返回的字符串
     */
    private void doGet(String httpUrl, String queryParam) {
        if (!TextUtils.isEmpty(queryParam)) {
            httpUrl += "?" + queryParam;
        }
        final Request request = new Request.Builder().url(httpUrl).build();
        final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                MainActivity.this.runOnUiThread(() -> {
                    Toast.makeText(MainActivity.this, "出现异常：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    String result = response.body().string();
                    if (!TextUtils.isEmpty(result)) {
                        MainActivity.this.runOnUiThread(() -> binding.tvResponse.setText(result));

//                    Gson gson = new Gson();
//                    final ResponseEntity responseEntity = gson.fromJson(result, ResponseEntity.class);
//                    if (responseEntity != null && responseEntity.getCode() == 200) {
//                        runOnUiThread(() -> binding.tvResponse.setText((String) responseEntity.getData()));
//                    }
                    } else {
                        MainActivity.this.runOnUiThread(() -> binding.tvResponse.setText("no data"));
                    }
                }
            }
        });
    }

    /**
     * POST方式的网络请求
     *
     * @param httpUrl 网址
     * @param param   请求字符串，格式为json字符串
     * @return 服务器端返回的字符串
     */
    private void doPost(@NonNull String httpUrl, @NonNull String param) {
        // 设置传输数据的媒体类型
        MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8");
        // 创建请求体数据
        RequestBody body = RequestBody.Companion.create(param, mediaType);
        // POST请求
        Request request = new Request.Builder()
                .post(body)
                .url(httpUrl)
                .build();
        final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                MainActivity.this.runOnUiThread(() -> {
                    Toast.makeText(MainActivity.this, "出现异常：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    String result = response.body().string();
                    if (!TextUtils.isEmpty(result)) {
                        MainActivity.this.runOnUiThread(() -> binding.tvResponse.setText(result));
                    }
                }
            }
        });
    }

    private void getMessage(String url) {
        Request request = new Request.Builder().url(url).build();
        new OkHttpClient.Builder().build().newCall(request)
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {

                    }

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        if (response.isSuccessful() && response.body() != null) {
                            final String result = response.body().string();
                            if (!TextUtils.isEmpty(result)) {
                                Gson gson = new Gson();
                                final ResponseEntity responseEntity = gson.fromJson(result, ResponseEntity.class);
                                if (responseEntity != null && responseEntity.getCode() == 200) {
                                    Message msg = handler.obtainMessage();
                                    msg.what = WEB_ID;
                                    msg.obj = responseEntity.getData();
                                    handler.sendMessage(msg);
                                }
                            }
                        }
                    }
                });
    }

    private void getWeather(String city) {
        // 组合请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("city", city);
        params.put("key", API_KEY);
        String httpUrl = WEATHER_URL + "?" + urlencode(params);

        // 创建OkHttpClient对象（创建机场）
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(5000, TimeUnit.MILLISECONDS)
                .build();
        // 构建Request对象（飞行目的地）
        Request request = new Request.Builder().url(httpUrl).build();
        // 构建Call对象（本次航班）, 发送异步请求（飞机进入就绪跑道）
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                // 处理异常信息（本次航班失败）
                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "请求失败：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response)
                    throws IOException {
                // 处理服务器返回的数据（抵达目的地）
                if (response.isSuccessful() && response.body() != null) {
                    final String body = response.body().string();
                    if (!TextUtils.isEmpty(body) && !body.contains("超过每日可允许请求次数"))  {
                        // 将JSON数据转为Java对象
                        Gson gson = new Gson();
                        Weather weather = gson.fromJson(body, Weather.class);
                        // handler发送消息
                        Message msg = handler.obtainMessage();
                        msg.what = WEATHER_ID;
                        msg.obj = weather;
                        handler.sendMessage(msg);
                    } else {
                        MainActivity.this.runOnUiThread(() -> {
                            binding.tvResponse.setText(body);
                        });
                    }
                }
            }
        });
    }

    /**
     * 将map类型转为请求参数型
     *
     * @param data Map类型参数
     * @return 请求字符串
     */
    private static String urlencode(Map<String, ?> data) {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, ?> entry : data.entrySet()) {
            try {
                builder.append(entry.getKey()).append("=")
                        .append(URLEncoder.encode(entry.getValue() + "", "UTF-8"))
                        .append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        String result = builder.toString();
        return result.substring(0, result.lastIndexOf("&"));
    }

    private void uploadFile() {
        RequestBody formBody = new FormBody.Builder()
                .add("search", "okhttp")
                .build();
        Request request = new Request.Builder()
                .url("https://en.wikipedia.org/w/index.php")
                .post(formBody)
                .build();
    }

    private static final MediaType JPG = MediaType.parse("image/jpeg");

    private void postMultipart(String url, String fileName) {
        RequestBody fileBody = RequestBody.create(fileName, JPG);
        RequestBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("title", "头像")
                .addFormDataPart("file", fileName, fileBody)
                .build();
        Request request = new Request.Builder().url(url).post(body).build();
        // 创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(5000, TimeUnit.MILLISECONDS)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(MainActivity.class.getSimpleName(), e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(MainActivity.class.getSimpleName(), response.body().string());
            }
        });
    }

    // 上传文件
    private void postMultipart(String url, InputStream inputStream) {
        // 创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(5000, TimeUnit.MILLISECONDS)
                .build();
        MediaType jpgType = MediaType.parse("image/jpeg");
        RequestBody requestBody = create(jpgType, inputStream);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                // Log.e(MainActivity.class.getSimpleName(), e.getMessage());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                // Log.d(MainActivity.class.getSimpleName(), response.body().string());
            }
        });
    }

    private static RequestBody create(MediaType contentType, InputStream inputStream) {
        return new RequestBody() {
            @Nullable
            @Override
            public MediaType contentType() {
                return contentType;
            }

            @Override
            public long contentLength() {
                try {
                    return inputStream.available();
                } catch (IOException e) {
                    return 0;
                }
            }

            @Override
            public void writeTo(@NotNull BufferedSink bufferedSink) throws IOException {
                Source source = null;
                try {
                    source = Okio.source(inputStream);
                    bufferedSink.writeAll(source);
                } finally {
                    Util.closeQuietly(source);
                }
            }
        };
    }
}